package server

import (
	"crypto/sha1"
	"encoding/base64"
	"net/http"
	"strings"
	"ws-demo-go/pkg/ws/common"
)

// Upgrade 将 HTTP 连接升级为 WebSocket 连接
func Upgrade(w http.ResponseWriter, r *http.Request) (common.Conn, error) {
	// 1. 验证请求方法和头
	if r.Method != http.MethodGet {
		return nil, common.ErrHandshakeFailed
	}
	if !strings.EqualFold(r.Header.Get("Upgrade"), "websocket") {
		return nil, common.ErrHandshakeFailed
	}
	if !strings.EqualFold(r.Header.Get("Connection"), "upgrade") {
		return nil, common.ErrHandshakeFailed
	}

	// 2. 获取并验证 Sec-WebSocket-Key
	key := r.Header.Get("Sec-WebSocket-Key")
	if key == "" {
		return nil, common.ErrHandshakeFailed
	}

	// 3. 计算 Sec-WebSocket-Accept
	h := sha1.New()
	h.Write([]byte(key + common.WebsocketGUID))
	accept := base64.StdEncoding.EncodeToString(h.Sum(nil))

	// 4. 发送 101 响应，完成升级
	w.Header().Set("Upgrade", "websocket")
	w.Header().Set("Connection", "Upgrade")
	w.Header().Set("Sec-WebSocket-Accept", accept)
	w.WriteHeader(http.StatusSwitchingProtocols)

	// 5. 获取底层 TCP 连接（从 ResponseWriter 中提取）
	hijacker, ok := w.(http.Hijacker)
	if !ok {
		return nil, common.ErrHandshakeFailed
	}
	netConn, _, err := hijacker.Hijack()
	if err != nil {
		return nil, err
	}

	// 6. 创建 WebSocket 连接实例
	return common.NewConn(netConn), nil
}
